home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Julian / Julian.m < prev    next >
Text File  |  1995-06-12  |  8KB  |  449 lines

  1. #import "Julian.h"
  2. #import <math.h>
  3. #import <stdlib.h>
  4. #import <sys/time.h>
  5. #import <stdio.h>
  6. @implementation Julian
  7.  
  8. // getEasterDay will only work for years between 1900 and 2099.
  9. // It takes a year and gives the day and month for easterDay
  10.  
  11. + (void)     getEasterDay    :(int ) year 
  12.                      :(int *) day
  13.                     :(int *) month    
  14.  
  15. {
  16.      int a,b,c,d,e,s,t,theDay,theMonth;
  17.  
  18.       a = year % 19;
  19.       b = year % 4;
  20.       c = year % 7;
  21.       s = 19*a+24;
  22.       d = s % 30;
  23.       t = 2*b+4*c+6*d+5;
  24.       e = t % 7;
  25.       theDay = 22+d+e;
  26.       if  (theDay >= 32)  {
  27.             theMonth = 4;
  28.             theDay= d+e-9;
  29.             if (theDay == 26) {
  30.                    theDay = 19;
  31.         }
  32.             else {
  33.                    if  (theDay == 25 && a == 16 && d == 28)  {
  34.                      theDay = 18;
  35.               }
  36.         }
  37.     }
  38.       else {
  39.             theMonth = 3;
  40.       }
  41.     
  42.     *day = theDay;
  43.     *month = theMonth;
  44.     
  45.     return;
  46. }
  47.  
  48.  
  49. +  (double) getCurrentDate
  50. {
  51.     int mon,mday,year,hr,min,sec,dow;
  52.     long theDate;
  53.     double theDDate;
  54.     
  55.     struct timeval tp;
  56.     struct timezone tz;
  57.     struct tm *theTime;
  58.     gettimeofday(&tp, &tz);
  59.     theTime = localtime(&(tp.tv_sec));
  60.     
  61.     theDDate = [Julian julianDay:theTime->tm_mday
  62.                                             :theTime->tm_mon+1
  63.                                             :theTime->tm_year+1900
  64.                                             :theTime->tm_hour
  65.                                             :theTime->tm_min
  66.                                             :theTime->tm_sec];
  67.             
  68.     theDate = [Julian julianDay:theTime->tm_mday
  69.                                             :theTime->tm_mon+1
  70.                                             :theTime->tm_year+1900];
  71.             
  72.     #ifdef DEBUG    
  73.         printf("the date is %f\n",theDDate);
  74.     #endif
  75.     
  76.     [Julian calendarDay:theDDate:&mday:&mon:&year:&hr:&min:&sec];
  77.     
  78.     dow = [Julian dow:theDate];
  79.     
  80.     #ifdef DEBUG
  81.         printf(" mm/dd/yy hh:mm:ss  = %02i/%02i/%04i  %02i:%02i:%02i and dow = %i\n"
  82.         ,mon,mday,year,hr,min,sec,dow);
  83.     #endif
  84.     
  85.     return theDDate;
  86. }
  87.  
  88.  
  89.  
  90. // Given a day month and year, calculate the julian date.
  91. + (double) julianDay:(int) day :(int) month :(int) year
  92. {
  93. int a,b;
  94. double retVal;
  95.  
  96. float yearCorr;
  97.  
  98.     //Correct for negitive year
  99.     yearCorr = (year > 0? 0.0 : 0.75);
  100.     if( month <= 2)
  101.     {
  102.         year--;
  103.         month += 12;
  104.     }
  105.     b = 0;
  106.     //Deal with Gregorian reform
  107.     if( (year * 10000.0) + (month * 100.0) + day >= 15821015.0)
  108.     {
  109.         a = year / 100;
  110.         b = (2-a)+(a/4);
  111.     }
  112.     
  113.     retVal = (long) ( (365.25 * year) - yearCorr);
  114.     retVal += (long) (30.6001 * (month+1));
  115.     retVal += (long) day;
  116.     retVal += 1720994L;
  117.     retVal += (long) b;
  118.     return(retVal);
  119. }
  120.  
  121. + (double)    julianDay    :(int) day
  122.                                  :(int) month
  123.                                 :(int) year
  124.                                 :(int) hour
  125.                                 :(int) min
  126.                                 :(int) sec
  127. {
  128. double retVal;
  129. double retFraction;
  130.  
  131.  
  132.     retVal = [self julianDay:day:month:year];
  133.     
  134.     retFraction =         (double)((double)hour/24.0)
  135.                          + (double)((double)min/1440.0)
  136.                          + (double)((double)sec/86400.0);
  137.                                                   
  138.     return  (retVal+retFraction);
  139. }
  140.  
  141.  
  142. //Given a julian date, calculate the month day and year.
  143. //The year will be Negitive if it's BC
  144. + (void)     calendarDay    :(double)julian
  145.                                 :(int *)    day
  146.                                 :(int *)    month
  147.                                 :(int *) year
  148. {
  149. long a,b,c,d,e,z, alpha;
  150.     
  151.     z = julian + 1;
  152.     //Deal with Gregorian reform
  153.     if( z < 2299161L)
  154.         a = z;
  155.     else
  156.     {
  157.         alpha = (long) (( z - 1867216.25) / 36524.25);
  158.         a = z + 1 + alpha - alpha / 4;
  159.     }
  160.     b = a + 1524;
  161.     c = (long) (( b - 122.1) / 365.25);
  162.     d = (long) (365.25 * c);
  163.     e = (long) (( b - d ) / 30.6001);
  164.     *day         = (int) b - d - (long) (30.6001 * e);
  165.     *month     = (int) ( e < 13.5) ? e - 1 : e - 13;
  166.     *year     = (int) (*month > 2.5) ? (c - 4716) : c - 4715;
  167. }
  168.  
  169. + (void)     calendarDay    :(double)    julian
  170.                                 :(int *)    day
  171.                                 :(int *)    month
  172.                                 :(int *) year
  173.                                 :(int *)    hour
  174.                                 :(int *)    min
  175.                                 :(int *) sec
  176. {
  177. double fractionalPart;
  178. double tmpResult;
  179. double integerPart;
  180.  
  181.     [self calendarDay    :(long) julian
  182.                             : day
  183.                             : month
  184.                             : year];
  185.     //days.fractionalDays
  186.     fractionalPart = modf((double)julian,&integerPart);
  187.         
  188.     tmpResult = fractionalPart * 24.0;
  189.     fractionalPart = modf(tmpResult,&integerPart);
  190.     *hour = (int) integerPart;
  191.     
  192.     tmpResult  = fractionalPart *  60.0;
  193.     fractionalPart = modf(tmpResult,&integerPart);
  194.     *min = (int) integerPart;
  195.     
  196.     tmpResult  = fractionalPart *  60.0;
  197.     fractionalPart = modf(tmpResult,&integerPart);
  198.     *sec = (int) integerPart;
  199.         
  200. }
  201.  
  202. //See if the passed in date is a Valid date
  203. // I.E. Feb 29 on a non leap year is NOT valid
  204. // returns YES if date is OK
  205. + (BOOL)     validDay        :(int)    day
  206.                         :(int)    month
  207.                         :(int)    year
  208. {
  209. int calDay;
  210. int calMonth;
  211. int calYear;
  212.  
  213.     //convert it to julian
  214.     [self calendarDay:[self julianDay:day:month:year]
  215.                             : &calDay
  216.                             : &calMonth
  217.                             : &calYear];
  218.     
  219.     return(( day == calDay) && (month == calMonth) && (year == calYear) );
  220.     
  221. }
  222.  
  223.  
  224.  
  225. + (BOOL)     validDay        :(int)    day
  226.                                 :(int)    month
  227.                                 :(int)    year
  228.                                 :(int)    hour
  229.                                 :(int)    min
  230.                                 :(int)    sec
  231. {
  232. int calDay;
  233. int calMonth;
  234. int calYear;
  235. int calHour;
  236. int calMin;
  237. int calSec;
  238.  
  239.     //convert it to julian
  240.     [self calendarDay:[self julianDay:day:month:year:hour:min:sec]
  241.                             : &calDay
  242.                             : &calMonth
  243.                             : &calYear
  244.                             : &calHour
  245.                             : &calMin
  246.                             : &calSec];
  247.     return(     (day == calDay)
  248.             && (month == calMonth)
  249.             && (year == calYear)
  250.             && (hour == calHour)
  251.             && (min == calMin)
  252.             && (sec == calSec)
  253.             );
  254. }
  255.  
  256. //0=Sunday 2 = Monday .... 6 = Saturday
  257. + (int)        dow:(long) julian
  258. {
  259.     return (int) ((( julian + 2) % 7) + 1);
  260. }
  261.  
  262. //week days from past dates
  263. + (double)     wkd:(int)    day
  264.                 :(int)    month
  265.                 :(int)    year
  266. {
  267. long d;
  268. double g;
  269. double f;
  270. double ans;
  271.  
  272.  
  273.     g = (month > 2) ? year : year-1;
  274.     f = (month > 2) ? month + 1 : month + 13;
  275.     
  276.     
  277.     d = day - (int) ( 0.75* (int) (g/100.0)-7) +
  278.                     (int) (365.25*g) + (int) (30.6*f);
  279.     
  280.     d-=2;                
  281.     ans = (5* (int) (d/7)) + (0.5*(int) (1.801* (d % 7)));
  282.     return ans;
  283. }
  284.  
  285.  
  286.  
  287.  
  288. //  Day of year
  289. + (int)     doy:(int)    day
  290.                 :(int)    month
  291.                 :(int)    year
  292. {
  293. double curJulianDay;
  294. double janJulianDay;
  295.  
  296.     curJulianDay =[Julian  julianDay:(int) day
  297.                                             :(int) month
  298.                                             :(int) year];
  299.                                             
  300.     janJulianDay = [Julian  julianDay:(int) 1
  301.                                             :(int) 1
  302.                                             :(int) year];
  303.                                     
  304.     return (int) ( (curJulianDay - janJulianDay) + 1.0);
  305. }
  306.  
  307.  
  308.  
  309. //instance methods
  310.  
  311. - init;
  312. {
  313.     julianDayVal = 0.0;
  314.     return self;
  315. }
  316. - (BOOL) initDay    
  317.                 :(int) month    
  318.                 :(int) day
  319.                 :(int) year
  320. {
  321.     [super init];
  322.     return [self setJulianDay:month:day:year];
  323. }
  324.                 
  325. - (BOOL) initDay    
  326.                 :(int) month    
  327.                 :(int) day
  328.                 :(int) year
  329.                 :(int) hour
  330.                 :(int) min
  331.                 :(int) sec
  332. {
  333.     [super init];
  334.     return [ self  setJulianDay
  335.                                 :month
  336.                                 :day
  337.                                 :year
  338.                                 :hour
  339.                                 :min
  340.                                 :sec];
  341. }
  342.  
  343. - read:(NXTypedStream *)stream
  344. {
  345.     [super read:stream];
  346.     /* class-specific code goes here */
  347.           NXReadType(stream,"d",&julianDayVal);
  348.  
  349.     return self;
  350. }
  351.  
  352. - write:(NXTypedStream *)stream
  353. {
  354.     [super write:stream];
  355.     /* class-specific archiving code goes here */
  356.      NXWriteType(stream,"d",&julianDayVal);
  357.     return self;
  358. }
  359.  
  360. - (double)     getJulianDay
  361. {
  362.     return julianDayVal;
  363. }
  364.  
  365.  
  366.  
  367. - (BOOL) setJulianDay    :(double) day
  368. {
  369.     julianDayVal = day;
  370.     return YES;
  371. }
  372.  
  373.  
  374. - (BOOL)    setJulianDay    :(int) month
  375.                                 :(int) day
  376.                                 :(int) year
  377. {
  378.     if( [Julian validDay    :(int) day
  379.                     :(int) month
  380.                     :(int) year])
  381.         {
  382.             julianDayVal = [Julian  julianDay:(int) month
  383.                                                         :(int) day
  384.                                                         :(int) year];
  385.             return YES;
  386.         }
  387.     return NO;
  388. }    
  389.                     
  390. - (BOOL) setJulianDay                :(int) day
  391.                                 :(int) month
  392.                                 :(int) year
  393.                                 :(int) hour
  394.                                 :(int) min
  395.                                 :(int) sec
  396. {
  397.     if( [Julian validDay                :(int) month
  398.                                 :(int) day
  399.                                 :(int) year
  400.                                 :(int) hour
  401.                                 :(int) min
  402.                                 :(int) sec])
  403.     {
  404.          julianDayVal = [Julian validDay    
  405.                                 :(int) month
  406.                                 :(int) day
  407.                                 :(int) year
  408.                                 :(int) hour
  409.                                 :(int) min
  410.                                 :(int) sec];
  411.         return YES;
  412.     }
  413.     return NO;
  414. }
  415.  
  416. -  getCalendarDay            :(int*) month
  417.                          :(int*) day
  418.                         :(int*) year
  419. {
  420.     [Julian calendarDay        : julianDayVal
  421.                             : day
  422.                             : month
  423.                             : year];
  424.     return self;
  425. }
  426.  
  427.         
  428.                         
  429. - getCalendarDay                :(int*) month
  430.                                  :(int*) day
  431.                                 :(int*) year
  432.                                  :(int*) hour
  433.                                  :(int*) min
  434.                                  :(int*) sec
  435. {
  436.     [Julian calendarDay            : julianDayVal
  437.                                 : day
  438.                                 : month
  439.                                 : year
  440.                                 : hour
  441.                                 : min
  442.                                 : sec];
  443.     
  444.     return self;
  445. }
  446.  
  447.  
  448. @end
  449.